From 82e03978b89938219958032efb1448cc76baa181 Mon Sep 17 00:00:00 2001
From: Saumit <justsaumit@protonmail.com>
Date: Sat, 27 Sep 2025 02:14:26 +0530
Subject: Initial snapshot - OpenTelemetry demo 2.1.3 -f

---
 src/frontend/pages/product/[productId]/index.tsx | 107 +++++++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 src/frontend/pages/product/[productId]/index.tsx

(limited to 'src/frontend/pages/product/[productId]/index.tsx')

diff --git a/src/frontend/pages/product/[productId]/index.tsx b/src/frontend/pages/product/[productId]/index.tsx
new file mode 100644
index 0000000..15766c8
--- /dev/null
+++ b/src/frontend/pages/product/[productId]/index.tsx
@@ -0,0 +1,107 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+import { NextPage } from 'next';
+import Head from 'next/head';
+import Image from 'next/image';
+import { useRouter } from 'next/router';
+import { useCallback, useState, useEffect } from 'react';
+import { useQuery } from '@tanstack/react-query';
+import Ad from '../../../components/Ad';
+import Footer from '../../../components/Footer';
+import Layout from '../../../components/Layout';
+import ProductPrice from '../../../components/ProductPrice';
+import Recommendations from '../../../components/Recommendations';
+import Select from '../../../components/Select';
+import { CypressFields } from '../../../utils/enums/CypressFields';
+import ApiGateway from '../../../gateways/Api.gateway';
+import { Product } from '../../../protos/demo';
+import AdProvider from '../../../providers/Ad.provider';
+import { useCart } from '../../../providers/Cart.provider';
+import * as S from '../../../styles/ProductDetail.styled';
+import { useCurrency } from '../../../providers/Currency.provider';
+
+const quantityOptions = new Array(10).fill(0).map((_, i) => i + 1);
+
+const ProductDetail: NextPage = () => {
+  const { push, query } = useRouter();
+  const [quantity, setQuantity] = useState(1);
+  const {
+    addItem,
+    cart: { items },
+  } = useCart();
+  const { selectedCurrency } = useCurrency();
+  const productId = query.productId as string;
+
+  useEffect(() => {
+    setQuantity(1);
+  }, [productId]);
+
+  const {
+    data: {
+      name,
+      picture,
+      description,
+      priceUsd = { units: 0, currencyCode: 'USD', nanos: 0 },
+      categories,
+    } = {} as Product,
+  } = useQuery({
+      queryKey: ['product', productId, 'selectedCurrency', selectedCurrency],
+      queryFn: () => ApiGateway.getProduct(productId, selectedCurrency),
+      enabled: !!productId,
+    }
+  ) as { data: Product };
+
+  const onAddItem = useCallback(async () => {
+    await addItem({
+      productId,
+      quantity,
+    });
+    push('/cart');
+  }, [addItem, productId, quantity, push]);
+
+  return (
+    <AdProvider
+      productIds={[productId, ...items.map(({ productId }) => productId)]}
+      contextKeys={[...new Set(categories)]}
+    >
+      <Head>
+        <title>Otel Demo - Product</title>
+      </Head>
+      <Layout>
+        <S.ProductDetail data-cy={CypressFields.ProductDetail}>
+          <S.Container>
+            <S.Image $src={"/images/products/" + picture} data-cy={CypressFields.ProductPicture} />
+            <S.Details>
+              <S.Name data-cy={CypressFields.ProductName}>{name}</S.Name>
+              <S.Description data-cy={CypressFields.ProductDescription}>{description}</S.Description>
+              <S.ProductPrice>
+                <ProductPrice price={priceUsd} />
+              </S.ProductPrice>
+              <S.Text>Quantity</S.Text>
+              <Select
+                data-cy={CypressFields.ProductQuantity}
+                onChange={event => setQuantity(+event.target.value)}
+                value={quantity}
+              >
+                {quantityOptions.map(option => (
+                  <option key={option} value={option}>
+                    {option}
+                  </option>
+                ))}
+              </Select>
+              <S.AddToCart data-cy={CypressFields.ProductAddToCart} onClick={onAddItem}>
+                <Image src="/icons/Cart.svg" height="15" width="15" alt="cart" /> Add To Cart
+              </S.AddToCart>
+            </S.Details>
+          </S.Container>
+          <Recommendations />
+        </S.ProductDetail>
+        <Ad />
+        <Footer />
+      </Layout>
+    </AdProvider>
+  );
+};
+
+export default ProductDetail;
-- 
cgit v1.2.3

